package cn.com.pc.content.service;

import cn.com.pc.content.domain.Biz;
import cn.com.pc.content.domain.content.ContentType;
import cn.com.pc.content.domain.Site;
import cn.com.pc.content.domain.metadata.ContentDataType;
import cn.com.pc.content.domain.metadata.ContentProperty;
import cn.com.pc.content.domain.metadata.ContentPropertyRepository;
import cn.com.pc.content.dto.ContentPropertyDTO;
import cn.com.pc.content.dto.PageForm;
import cn.com.pc.content.dto.PageResult;
import cn.com.pc.content.dto.Sort;
import cn.com.pc.content.service.es.ESCurdService;
import cn.com.pc.content.util.ContentUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.transaction.Transactional;
import java.io.IOException;

@Slf4j
@Service
public class MetadataService {

    @Autowired
    private ContentPropertyRepository contentPropertyRepository;

    @Autowired
    private ESCurdService esCurdService;


    /**
     * 新增元数据配置
     * @param contentPropertyDTO
     * @return
     * @throws IOException
     */
    @Transactional
    public Long createContentProperty(ContentPropertyDTO contentPropertyDTO) {
        if (contentPropertyDTO.getDataType() == ContentDataType.Object) {
            contentPropertyDTO.setHasIndex(false);
        }
        ContentProperty contentProperty = new ContentProperty();
        BeanUtils.copyProperties(contentPropertyDTO, contentProperty);
        // 保存元数据配置
        contentProperty = contentPropertyRepository.save(contentProperty);
        // 新增元数据索引
        if (contentProperty.getHasIndex()) {
            boolean success = this.setContentPropertyIndex(contentProperty);
            if (!success) {throw new RuntimeException("新增元数据索引失败");}
        }
        return contentProperty.getId();
    }


    /**
     * 查询元数据配置列表
     * @param contentPropertyDTO
     * @param pageForm
     * @param sort
     * @return
     */
    public PageResult<ContentProperty> listContentPropertyByDTO(ContentPropertyDTO contentPropertyDTO, PageForm pageForm, Sort sort) {
        ContentProperty contentProperty = new ContentProperty();
        contentProperty.setDeleted(false);
        if (contentPropertyDTO.getId() != null) {
            contentProperty.setId(contentPropertyDTO.getId());
        }
        if (StringUtils.hasLength(contentPropertyDTO.getName())) {
            contentProperty.setName(contentPropertyDTO.getName());
        }
        if (contentPropertyDTO.getSite() != null) {
            contentProperty.setSite(contentPropertyDTO.getSite());
        }
        if (contentPropertyDTO.getBiz() != null) {
            contentProperty.setBiz(contentPropertyDTO.getBiz());
        }
        if (contentPropertyDTO.getContentType() != null) {
            contentProperty.setContentType(contentPropertyDTO.getContentType());
        }
        if (contentPropertyDTO.getDataType() != null) {
            contentProperty.setDataType(contentPropertyDTO.getDataType());
        }
        if (contentPropertyDTO.getHasIndex() != null) {
            contentProperty.setHasIndex(contentPropertyDTO.getHasIndex());
        }
        if (contentPropertyDTO.getNeedAudit() != null) {
            contentProperty.setNeedAudit(contentPropertyDTO.getNeedAudit());
        }
        if (StringUtils.hasLength(contentPropertyDTO.getCreatedBy())) {
            contentProperty.setCreatedBy(contentPropertyDTO.getCreatedBy());
        }
        if (contentPropertyDTO.getCreatedAt() != null) {
            contentProperty.setCreatedAt(contentPropertyDTO.getCreatedAt());
        }

        Example<ContentProperty> example = Example.of(contentProperty);
        Pageable pageable;
        if (!StringUtils.hasLength(sort.getSortBy())) {
            sort.setSortBy("id");
        }
        pageable = PageRequest.of(pageForm.getPageNum() - 1, pageForm.getPageSize(), sort.getDirection(), sort.getSortBy());
        Page<ContentProperty> contentPropertyPage = contentPropertyRepository.findAll(example, pageable);

        return PageResult.fromPage(contentPropertyPage);
    }


    public void updateContentProperty(ContentProperty contentProperty) {
        contentPropertyRepository.save(contentProperty);
    }


    public ContentProperty findContentPropertyById(Long propertyId) {
        return contentPropertyRepository.findById(propertyId).orElse(null);
    }

    /**
     * 查找元数据配置
     * @param name
     * @param site
     * @param biz
     * @param contentType
     * @return
     */
    public ContentProperty getContentProperty(String name, Site site, Biz biz, ContentType contentType) {
        return contentPropertyRepository.findByNameAndSiteAndBizAndContentTypeAndDeleted(name, site, biz, contentType, false);
    }


    public boolean exixtsContentProperty(String name, Site site, ContentType contentType, ContentDataType dataType) {
        return contentPropertyRepository.existsByNameAndSiteAndContentTypeAndDataTypeNotAndDeleted(name, site, contentType, dataType, false);
    }


    /**
     * 新增元数据es索引
     * @param contentProperty
     * @return
     * @throws IOException
     */
    @SneakyThrows
    public boolean setContentPropertyIndex(ContentProperty contentProperty) {
        return esCurdService.insertMappingProperty(ContentUtils.getIndexName(contentProperty.getSite(), contentProperty.getContentType()), contentProperty.getName(), contentProperty.getDataType().getName());
    }

}
